<?php
namespace Plu\Library\Models\Tga\Live;

use Phalcon\Mvc\Model,
    Phalcon\DI,
    Phalcon\Db\Column,
    Phalcon\Mvc\Model\Resultset\Simple as Resultset,
    Plu\Library\Models\Platform\Tag\TagMap as TagMapModel;

class Games extends Model {
    public $id;
    public $name;
    public $tag;
    public $parentid;
    public $mobilelogo;
    public $logo;
    public $icon;
    public $channels;
    public $views;
    public $_index;
    public $skin;
    public $lastupdate;

    const CACHE_TIME = 60;

    const SKIN_TGA = 4;
    const SKIN_PLU = 2;


    public function getSource() {
        return "tgagames";
    }

    public function initialize() {
        $this->setReadConnectionService("db.longzhulivereadonly.slave");
        $this->setWriteConnectionService('db.longzhulive');
    }

    /**
     * 获取所有游戏数据
     */
    static public function getGames($skin = self::SKIN_TGA, $filter = null) {
        $guid = sprintf('tgagames_%s', $skin);
        $cache_handler = DI::getDefault()->get('cache');

        $items = $cache_handler->get($guid, self::CACHE_TIME);
        $phql = "";

        if (!empty($filter) && !is_array($filter)) {
            $filter = [$filter];
        }

        if (is_array($skin) || is_null($skin)) {
            $skin = self::SKIN_TGA;
        }

        for($i = 0, $len = count($filter); $i < $len; $i++) {
            $fid = $filter[$i];
            $phql .= " AND id <> $fid";
        }

        if (empty($items)) {
            $data = self::find(array(
                'skin & :skin: = :skin:'. $phql,
                'bind'    => array(
                    'skin' => $skin
                )
            ));

            $data = $data->toArray();

            $items = self::sorting($data);

            $cache_handler->save($guid, $items, self::CACHE_TIME);
        }

        return $items;
    }

    /**
     * 对游戏数据进行排序及整理
     */
    static private function sorting($data) {
        $items = array();
        $_subgames = array();

        //支持无限级分类 数据自动合并计算
        for ($i = 0, $len = count($data); $i < $len; $i++) {
            $game = $data[$i];
            //tag it's node
            $game['islast'] = 1;
            $items[$game['id']] = $game;

            $parentid = $game['parentid'];
            if ($parentid > 0) {
                if (empty($_subgames[$parentid])) {
                    $_subgames[$parentid] = array(
                        'items'    => array(),
                        'views'    => 0,
                        'channels' => 0
                    );
                }
                $_subgames[$parentid]['items'][] = $game['id'];
                $_subgames[$parentid]['views'] += $game['views'];
                $_subgames[$parentid]['channels'] += $game['channels'];
            }
        }

        if (!empty($_subgames)) {
            foreach ($_subgames as $gameid => $data) {
                if (!empty($items[$gameid])) {
                    $item = $items[$gameid];

                    $item['islast'] = 0;
                    $items[$gameid] = $item;

                    $parentId = $item['parentid'];

                    if ($parentId > 0) {
                        //合并到上层的parnet
                        if (empty($items[$parentId]['subgames'])) {
                            $_items = $_subgames[$parentId]['items'];
                        } else {
                            $_items = $items[$parentId]['subgames'];
                        }

                        //累加数据
                        if (!empty($items[$parentId])) {
                            $items[$parentId]['subgames'] = array_values(array_unique(array_merge($_items, $data)));
                            $items[$parentId]['views']    += $_subgames[$parentId]['views'];
                            $items[$parentId]['channels'] += $_subgames[$parentId]['channels'];
                        }
                    }

                    if (empty($items[$gameid]['subgames'])) {
                        $items[$gameid]['subgames'] = $data['items'];
                    }
                    $items[$gameid]['subgames'][] = $gameid;
                    $items[$gameid]['views'] += $data['views'];
                    $items[$gameid]['channels'] += $data['channels'];
                }
            }
        }

        usort($items, function($a, $b) {
            if ($a['channels'] > $b['channels']) {
                return -1;
            }
            if ($a['channels'] < $b['channels']) {
                return 1;
            }
            if ($a['views'] > $b['views']) {
                return -1;
            }
            if ($a['views'] < $b['views']) {
                return 1;
            }
            return 0;
        });

        //手动调调顺序
        $need_insert_data = array_filter($items, function($item) {
            return $item['_index'] > 0;
        });
        $items = array_filter($items, function($item) {
            return $item['_index'] == 0;
        });

        usort($need_insert_data, function($a, $b) {
            if ($a['_index'] > $b['_index']) {
                return 1;
            }
            if ($a['_index'] < $b['_index']) {
                return -1;
            }
            return 0;
        });

        foreach ($need_insert_data as $item) {
            $_index = $item['_index'];
            //插入需要的数据,这里的index必须减1
            array_splice($items, ($_index - 1), 0, array($item));
        }

        return $items;
    }

    static private function formatGame($game) {
        return array(
            "game" => array(
                "id"   => $game['id'],
                "name" => $game['name'],
                "logo" => $game['logo'],
                'tag'  => $game['tag'],
                'icon' => $game['tag'],
                "url"  => '/games/'.$game['tag'],
                "parentid" => (int)$game['parentid'],
                "subgames" => isset($game['subgames']) ? $game['subgames'] : array()
            ),
            "channels"=> (int)$game['channels'],
            "viewers"=> (int)$game['views'],
        );
    }

    static public function getFormattedGames($skin = self::SKIN_TGA,$filter = null) {
        $games = self::getGames($skin, $filter);

        $items = array();
        array_walk($games, function($game) use (&$items) {
            $items[] = self::formatGame($game);
        });

        return $items;
    }
}
